﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TcpIpServerTest.Network
{
    public delegate void TcpConnectionAcceptedDelegate(TcpConnection tcpConnection);

    public class TcpService
    {
        IPEndPoint selfIPEndPoint;
        TcpListener tcpListener;
        bool listening = false;

        public TcpConnectionAcceptedDelegate TcpConnectionAccepted;

        public void Start(IPEndPoint ipEndPoint)
        {
            selfIPEndPoint = ipEndPoint;
            //tcpListener = new TcpListener(selfIPEndPoint);
            tcpListener = new TcpListener(selfIPEndPoint);
            tcpListener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            tcpListener.Server.NoDelay = true;
            tcpListener.Start();
            listening = true;
            tcpListener.BeginAcceptTcpClient(new AsyncCallback(OnAcceptTcpCliet), null);
        }
        int conNumber = 0;
        void OnAcceptTcpCliet(IAsyncResult result)
        {
            if (listening)
            {                
                TcpClient client = tcpListener.EndAcceptTcpClient(result);
                client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                client.Client.NoDelay = true;
                if (TcpConnectionAccepted != null)
                {
                    Thread thread = new Thread(new ParameterizedThreadStart(
                        delegate(object obj)
                        {
                            TcpConnectionAccepted((TcpConnection)obj);
                    }));
                    conNumber++;
                    TcpConnection con = new TcpConnection(client);
                    con.connectionNumber = conNumber;
                    thread.Start(con);
                }
            }
            if (listening)
            {
                tcpListener.BeginAcceptTcpClient(new AsyncCallback(OnAcceptTcpCliet), null);
            }
        }

        public void Stop()
        {
            listening = false;
            if (tcpListener != null)
            {
                tcpListener.Stop();
            }
        }
    }
}
